﻿namespace UiFramework
{
    // 界面管理器
    export class StateMgr
    {
        // 界面储存
        UiPile: Array<IState>;
        // 当前显示的界面
        curState: IState = null;
        // 主 div
        div: HTMLDivElement = null;
        constructor()
        {
            this.UiPile = new Array<IState>();
        }

        /**
         * 切换界面
         * @param state 要切的界面
         */
        changeState(state: IState, message: any = null, animationName: SkipAnimation = null, animationMessage: any = null)
        {
            if (animationName != null) {
                let curState1 = this.curState;
                this.curState = state;
                this.UiPile.push(state);
                this.curState.onInit(this);
                animationName.onInit(this, curState1, state, true, animationMessage);
                if (message != null)
                    this.curState.onMessage(message);
            } else {
                if (this.curState != null)
                    this.curState.onHide();
                this.curState = state;
                if (this.curState != null) {
                    this.UiPile.push(state);
                    this.curState.onInit(this);
                    if (message != null)
                        this.curState.onMessage(message);
                }
            }
        }

        /**
         * 切换界面
         * @param name 界面的名字
         */
        changeStateByName(name: string, message: any = null, animationName: string = null, animationMessage: any = null)
        {
            if (name == null)
                this.changeState(null);
            else
            {
                let getstate: () => IState =
                    UiMap[name];
                if (animationName != null) {
                    let getAnimation: () => SkipAnimation = AnimationMap[animationName];
                    this.changeState(getstate(), message, getAnimation(), animationMessage);
                } else {
                    this.changeState(getstate(), message);
                }
            }
        }

        /**
         * 关闭界面
         * @param state 需要关闭的界面
         */
        finish(state: IState, animationName: string = null, animationMessage: any = null)
        {
            if (state == this.curState && animationName != null) {
                this.finishAnimation(animationName, animationMessage);
            } else {
                this.finishCall(state);
            }
        }

        finishCall(state: IState, is = true) {
            for (let i = 0; i < this.UiPile.length; i++) {
                if (this.UiPile[i] == state) {
                    this.UiPile[i].onExit();
                    if (i == (this.UiPile.length - 1)) {
                        if (this.UiPile.length != 1) {
                            this.UiPile.splice(i, 1);
                            this.curState = this.UiPile[this.UiPile.length - 1];
                            if (is)
                                this.UiPile[this.UiPile.length - 1].onRecover(null);
                        }
                    }
                    return;
                }
            }
        }

        finishAnimation(animationName: string, animationMessage: any = null) {
            if (this.UiPile.length > 2) {
                let priorUi = this.UiPile[this.UiPile.length - 2];
                priorUi.onRecover((this.curState as UiAbstract).divSelf);
                let getAnimation: () => SkipAnimation = AnimationMap[animationName];
                let Animation = getAnimation();
                Animation.onInit(this, priorUi, this.curState, false, androidMessage);
            }
            
        }
    }


    /**
     * 界面状态
     */
    export interface IState
    {
        onInit(smgr: StateMgr);
        onExit();
        onHide();
        onRecover(element: HTMLDivElement);
        onMessage(meassge: any);
        onEvent(event: SmartEvent);
    }

    /**
     * 窗口界面
     */
    export interface DialogState
    {
        onInit(div: HTMLDivElement);
        onmessage(meassage: any);
        onExit();
    }
    ;
    /**
    *跳转动画
    */
    export interface SkipAnimation {
        onInit(smgr: StateMgr, ui1: IState, ui2: IState, isSkip: boolean, onMessage: any);
        onEnd();
    }

    export abstract class SkipAnimationAbstract implements SkipAnimation {
        smgr: StateMgr;
        private ui1: IState;//前一个界面
        private ui2: IState;//打开的的界面
        private ui1_css: string;
        private ui2_css: string;
        private onEndListener;
        ui1_div: HTMLDivElement;
        ui2_div: HTMLDivElement;
        isSkip: boolean;//判断是跳转还是关闭
        onInit(smgr: StateMgr, ui1: IState, ui2: IState, isSkip: boolean, onMessage: any = null) {
            this.smgr = smgr;
            this.onEndListener = this.onEnd.bind(this);
            if (ui1 != null) {
                this.ui1 = ui1;
                this.ui1_div = (ui1 as UiAbstract).divSelf;
                this.ui1_css = this.ui1_div.className;

            }
            if (ui2 != null) {
                this.ui2 = ui2;
                this.ui2_div = (ui2 as UiAbstract).divSelf;
                this.ui2_css = this.ui2_div.className;
            }
            this.isSkip = isSkip;
           
            
            this.onStart();

        }

        abstract onStart() ;

        onEnd() {
            if (this.ui1 != null) {
                this.ui1_div.className = this.ui1_css;
            }
            if (this.ui2 != null) {
                this.ui2_div.className = this.ui2_css;
            }

            if (this.isSkip) {
                if (this.ui1 != null) 
                    this.ui1.onHide();
            } else {
                if (this.ui2 != null)
                    this.smgr.finishCall(this.ui2, false);
            }
        }
    }

    /**
     * 界面继承类
     */
    export abstract class UiAbstract implements IState
    {
        stateMgr: StateMgr; // 界面管理器
        divSelf: HTMLDivElement; // 当前界面 div
        DialogArray: Array<DialogState>;

        // 初始化
        onInit(smgr: StateMgr)
        {
            this.stateMgr = smgr;
            this.divSelf = document.createElement("div");
            this.divSelf.style.width = "100%";
            this.divSelf.style.height = "100%";
            this.divSelf.style.position = "absolute";
            this.stateMgr.div.appendChild(this.divSelf);
            this.onStart(this.divSelf);
        }

        // 界面加载
        abstract onStart(divSelf: HTMLDivElement);
        // 界面结束
        abstract onEnd();

        // 界面传值
        onMessage(meassge: any)
        {

        }

        // 界面隐藏
        onHide()
        {
            this.stateMgr.div.removeChild(this.divSelf);
        }

        // 界面恢复
        onRecover(element: HTMLDivElement = null)
        {
            this.stateMgr.div.appendChild(this.divSelf);
        }

        // 主机物理按键事件
        onEvent(event: SmartEvent)
        {
            if (event == SmartEvent.Return)
            {
                if (this.DialogArray != null && this.DialogArray.length != 0)
                {
                    this.DialogArray.pop().onExit();
                } else
                {
                    this.finish();
                }
            }
        }

        // 打开弹出框
        openDialog(var1: string, message: any = null): Dialog
        {
            if (this.DialogArray == null)
            {
                this.DialogArray = [];
            }
            let open: () => DialogState = DialogMap[var1];
            let dialog = open();
            this.DialogArray.push(dialog);
            dialog.onInit(this.divSelf);
            if (message != null)
                dialog.onmessage(message);
            return dialog as Dialog;
        }

        delDialog(dialog: DialogState)
        {
            dialog.onExit();
        }

        // 界面结束
        onExit()
        {
            this.onEnd();
            this.stateMgr.div.removeChild(this.divSelf);
        }

        // 关闭界面
        finish()
        {
            this.stateMgr.finish(this);
        }

    }

    export abstract class Dialog implements DialogState
    {
        // 窗口界面
        divSelf: HTMLDivElement;
        // 依存的 ui 界面
        private UIdiv: HTMLDivElement;

        onInit(div: HTMLDivElement)
        {
            this.UIdiv = div;
            this.divSelf = document.createElement("div") as HTMLDivElement;
            this.divSelf.style.position = "absolute";
            this.divSelf.style.left = "0px";
            this.divSelf.style.top = "0px";
            this.divSelf.style.width = "100%";
            this.divSelf.style.height = "100%";
            this.divSelf.style.backgroundColor = "rgba(0,0,0,0.2)";
            div.appendChild(this.divSelf);
            this.onStart(this.divSelf);
        }

        // 界面加载
        abstract onStart(divSelf: HTMLDivElement);

        // 界面传值
        onmessage(meassage: any)
        {
        }

        // 界面关闭
        onExit()
        {
            this.UIdiv.removeChild(this.divSelf);
        }
    }
}